package com.gzx.bi.modular.screen.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.gzx.bi.modular.screen.constant.StatisticBIConstant;
import com.gzx.bi.modular.screen.mapper.GzxBICallRecordMapper;
import com.gzx.bi.modular.screen.service.GzxBICallRecordService;
import com.gzx.bi.modular.screen.service.GzxPredictAllService;
import com.gzx.bi.modular.screen.service.GzxStatisticBIService;
import com.gzx.bi.modular.screen.util.ScreenDateUtils;
import com.gzx.bi.modular.screen.vo.*;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Service;
import vip.xiaonuo.common.util.CommonDateUtil;
import vip.xiaonuo.sys.feign.SysOrgFeign;
import vip.xiaonuo.sys.feign.SysUserFeign;

import java.util.*;

/**
 * bi报表服务实现类
 *
 * @author xbl
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class GzxBICallRecordServiceImpl implements GzxBICallRecordService {

    //话单mapper
    private final GzxBICallRecordMapper biCallRecordMapper;

    //bi报表service
    private final GzxStatisticBIService biService;

    //组织feign
    private final SysOrgFeign sysOrgFeign;
    //用户feign
    private final SysUserFeign sysUserFeign;

    //线路
    private final GzxPredictAllService predictAllService;

    //根据ids获取sysorg信息调用组织Feign接口，只要id,name
    public List<SysOrg> getOrgByIds(List<String> orgIds) {
        List<SysOrg> list = new ArrayList<>();
        String orgListSelector = sysOrgFeign.orgListSelector(StatisticBIConstant.INT_VAL_0, StatisticBIConstant.INT_VAL_500, "");
        if (ObjectUtils.isEmpty(orgListSelector)) {
            return list;
        }
        //把orgListSelector转成json，然后从records中取list
        JSONObject json = JSON.parseObject(orgListSelector);
        List<SysOrg> sysOrgs = JSON.parseArray(json.getString("records"), SysOrg.class);
        //遍历sysOrgs，把ids中的id和org中的id对应上的返回
        for (SysOrg sysOrg : sysOrgs) {
            for (String orgId : orgIds) {
                if (!StringUtils.isEmpty(sysOrg.getId()) && sysOrg.getId().equals(orgId)) {
                    list.add(sysOrg);
                }
            }
        }
        //deptName不包含调解中心的都去掉
        list = list.stream().filter(org -> org.getName().contains(StatisticBIConstant.TJZX_STR)).toList();
        return list;
    }

    //根据用户ids获取sysuser信息
    public List<SysUser> getUserByIds(List<String> userIds) {
        List<SysUser> list = new ArrayList<>();
        Set<String> accountSet = new HashSet<>(userIds);
        String userListByIdWithException = sysUserFeign.getUserByAccount(accountSet);
        List<SysUser> sysUsers = JSON.parseArray(userListByIdWithException, SysUser.class);
        //遍历sysUsers，把ids中的id和org中的id对应上的返回
        for (SysUser sysUser : sysUsers) {
            for (String userId : userIds) {
                if (!StringUtils.isEmpty(sysUser.getAccount()) && sysUser.getAccount().equals(userId)) {
                    list.add(sysUser);
                }
            }
        }
        list = list.stream().filter(user -> ObjectUtils.isNotEmpty(user.getAccount())).toList();
        return list;
    }

    //生成本月通话统计报表
    @DS("tjzy-async")
    @Override
    public void scheduleBIMonthCall(GzxLocalDateTimeVo date) {
        //获取所有通话数量
        GzxMonthCallVo all = biCallRecordMapper.getDayAllByTime(date);
        all.setBiMonth(ScreenDateUtils.getDate(date.getStartDate()));
        //所有通话总数
        int total = all.getTotal();
        //获取呼出数量
        GzxMonthCallVo callOut = biCallRecordMapper.getDayCallOutByTime(date);
        all.setCallTotal(callOut.getCallTotal());
        all.setCallCompletionTotal(callOut.getCallCompletionTotal());
        all.setCallDurationOutgoing(callOut.getCallDurationOutgoing());
        all.setActiveSeatsNum(callOut.getActiveSeatsNum());
        //计算呼出接通率
        all.setCallCompletionRate(Double.parseDouble(String.format("%.2f", (double) callOut.getCallCompletionTotal() / total)));
        //获取呼入数量
        GzxMonthCallVo callIn = biCallRecordMapper.getDayCallInByTime(date);
        all.setTotalIncomingCall(callIn.getTotalIncomingCall());
        //计算呼入接通率
        all.setIncomingCallRate(Double.parseDouble(String.format("%.2f", (double) callIn.getTotalIncomingCall() / total)));

        //每天报表的调解员活跃数量
        GzxSeatsVo seat = new GzxSeatsVo();
        seat.setDate(ScreenDateUtils.getDate(date.getStartDate()));
        seat.setSeats(all.getActiveSeatsNum());
        all.setSeatVo(seat);

        //把vo对象转成jsonstr
        String jsonStr = JSON.toJSONString(all);

        log.info("当天 {} 通话统计 最新一版数据 -> {} ", date, jsonStr);
        //每天同一种报表只有一条数据，最新的数据会把之前的数据覆盖；这样前端查询的时候每次查出来这种报表的所有数据，合并之后返回即可
        biService.insertOnDuplicate(StatisticBIConstant.MONTH_CALL_STATISTICS_DAY, jsonStr, ScreenDateUtils.getDate(date.getStartDate()));
    }

    //团队坐席统计
    @DS("tjzy-async")
    @Override
    public void scheduleBITeamAgent(GzxLocalDateTimeVo date) {
        GzxTeamAgentVo teamAgentVo = new GzxTeamAgentVo();
        //获取所有职场的通话总量
        List<GzxCallTotalVo> allList = biCallRecordMapper.getCallTotalStatistics(date);
        //deptId下的数据少于50条的都过滤掉
        allList = allList.stream().filter(vo -> vo.getCallTotal() > StatisticBIConstant.FILTER_NUM).toList();
        List<String> orgIds = allList.stream().map(GzxCallTotalVo::getDeptId).toList();
        //为空的不去查询
        if (!orgIds.isEmpty()) {
            //根据deptId获取名称
            List<SysOrg> sysOrgs = getOrgByIds(orgIds);
            //把org中id和office的deptId对应上的赋值给office
            for (GzxCallTotalVo callTotalVo : allList) {
                for (SysOrg sysOrg : sysOrgs) {
                    //非空校验
                    if (!StringUtils.isEmpty(callTotalVo.getDeptId()) && callTotalVo.getDeptId().equals(sysOrg.getId())) {
                        callTotalVo.setDeptName(sysOrg.getName());
                    }
                }
            }
            log.info("团队坐席统计 - 获取deptName - sysOrgs:{},allList:{}", sysOrgs, allList);
        }
        if (!allList.isEmpty()) {
            teamAgentVo.setCallTotalList(allList);
        } else {
            teamAgentVo.setCallTotalList(new ArrayList<>());
        }
        //获取所有职场的呼叫总量
        List<GzxCallOutgoingVo> callList = biCallRecordMapper.getCallCompletionStatistics(date);
        //deptId下的数据少于50条的都过滤掉
        callList = callList.stream().filter(vo -> vo.getCallOutgoingTotal() > StatisticBIConstant.FILTER_NUM).toList();
        List<String> outOrgIds = allList.stream().map(GzxCallTotalVo::getDeptId).toList();
        //为空的不去查询
        if (!outOrgIds.isEmpty()) {
            //根据deptId获取名称
            List<SysOrg> sysOrgs = getOrgByIds(orgIds);
            //把org中id和office的deptId对应上的赋值给office
            for (GzxCallOutgoingVo callOutgoingVo : callList) {
                for (SysOrg sysOrg : sysOrgs) {
                    //非空校验
                    if (!StringUtils.isEmpty(callOutgoingVo.getDeptId()) && callOutgoingVo.getDeptId().equals(sysOrg.getId())) {
                        callOutgoingVo.setDeptName(sysOrg.getName());
                    }
                }
            }
            log.info("团队坐席统计 - 获取deptName - sysOrgs:{},callList:{}", sysOrgs, callList);
        }
        if (!callList.isEmpty()) {
            teamAgentVo.setCallOutgoingList(callList);
        } else {
            teamAgentVo.setCallOutgoingList(new ArrayList<>());
        }

        teamAgentVo.setBiType(StatisticBIConstant.TEAM_AGENT_STATISTICS_DAY);
        teamAgentVo.setBiMonth(ScreenDateUtils.getDate(date.getStartDate()));
        //把vo对象转成jsonstr
        String jsonStr = JSON.toJSONString(teamAgentVo);
        log.info("当天 {} 团队坐席统计 最新一版数据 -> {} ", date, jsonStr);

        biService.insertOnDuplicate(StatisticBIConstant.TEAM_AGENT_STATISTICS_DAY, jsonStr, ScreenDateUtils.getDate(date.getStartDate()));
    }

    //通话趋势分析
    @DS("tjzy-async")
    @Override
    public void scheduleBICallTrend(GzxLocalDateTimeVo date) {
        GzxCallTrendVo callTrendVo = new GzxCallTrendVo();
        //通话总量统计
        GzxCallSummaryVo summary = biCallRecordMapper.getCallSummary(date);
        int totalCall = summary.getTotal();
        summary.setCurrentDate(ScreenDateUtils.getDate(date.getStartDate()));
        //计算接通率
        double completionRate = (double) summary.getCompletionTotal() / totalCall;
        summary.setCompletionRate(Double.parseDouble(String.format("%.2f", completionRate)));
        callTrendVo.setCallSummary(summary);

        //通话趋势分析 - 呼叫类型分布 0：呼入；1：呼出；2：多人外呼
        List<GzxCommonVo> callTypeDistribution = biCallRecordMapper.getCallTypeDistribution(date);
        if (!callTypeDistribution.isEmpty()) {
            callTrendVo.setCallTypeDistribution(callTypeDistribution);
        } else {
            callTrendVo.setCallTypeDistribution(new ArrayList<>());
        }
        //通话趋势分析 - 呼叫结果分布
        List<GzxCommonVo> callResultDistribution = biCallRecordMapper.getCallResultDistribution(date);
        if (!callResultDistribution.isEmpty()) {
            callTrendVo.setCallResultDistribution(callResultDistribution);
        } else {
            callTrendVo.setCallResultDistribution(new ArrayList<>());
        }

        callTrendVo.setBiType(StatisticBIConstant.CALL_TREND_ANALYSIS_DAY);
        callTrendVo.setBiMonth(ScreenDateUtils.getDate(date.getStartDate()));
        //把vo对象转成jsonstr
        String jsonStr = JSON.toJSONString(callTrendVo);
        log.info("当天 {} 通话趋势分析 最新一版数据 -> {} ", date, jsonStr);

        biService.insertOnDuplicate(StatisticBIConstant.CALL_TREND_ANALYSIS_DAY, jsonStr, ScreenDateUtils.getDate(date.getStartDate()));
    }

    //坐席状态统计 团队在线时长统计（每天-各团队通话时长）；坐席在线时长统计（top10坐席通话时长）
    @DS("tjzy-async")
    @Override
    public void scheduleBIAgentStatus(GzxLocalDateTimeVo date) {
        //坐席状态统计
        GzxAgentStatusVo agentStatusVo = new GzxAgentStatusVo();
        //当天所有的职场
        GzxOfficeCallVo officeCallVo = new GzxOfficeCallVo();
        officeCallVo.setCurrentDate(ScreenDateUtils.getDate(date.getStartDate()));
        //每天调解中心的通话时长
        List<GzxOfficeVo> officeVos = biCallRecordMapper.getOfficeDuration(date);
        //deptId下的数据少于50条的都过滤掉
        officeVos = officeVos.stream().filter(vo -> vo.getTotalCallDuration() > StatisticBIConstant.FILTER_NUM).toList();
        List<String> orgIds = officeVos.stream().map(GzxOfficeVo::getDeptId).toList();
        //为空的不去查询
        if (!orgIds.isEmpty()) {
            //根据deptId获取名称
            List<SysOrg> sysOrgs = getOrgByIds(orgIds);
            //把org中id和office的deptId对应上的赋值给office
            for (GzxOfficeVo officeVo : officeVos) {
                for (SysOrg sysOrg : sysOrgs) {
                    //非空校验
                    if (!StringUtils.isEmpty(officeVo.getDeptId()) && officeVo.getDeptId().equals(sysOrg.getId())) {
                        officeVo.setDeptName(sysOrg.getName());
                    }
                }
            }
            log.info("坐席状态统计 - 获取deptName - sysOrgs:{},officeVos:{}", sysOrgs, officeVos);
        }
        if (!officeVos.isEmpty()) {
            officeCallVo.setOfficeVos(officeVos);
        } else {
            officeCallVo.setOfficeVos(new ArrayList<>());
        }
        //每天top10调解员的通话时长
        List<GzxAgentCallVo> agentCallVos = biCallRecordMapper.getAgentDuration(date);
        //根据userIds获取名称
        List<String> userIds = agentCallVos.stream().map(GzxAgentCallVo::getAgentId).toList();
        if (!userIds.isEmpty()) {
            List<SysUser> sysUsers = getUserByIds(userIds);
            //把user中id和agentCallVos的id对应上的赋值给agentCallVos
            for (GzxAgentCallVo agentCallVo : agentCallVos) {
                for (SysUser sysUser : sysUsers) {
                    //非空校验
                    if (!StringUtils.isEmpty(agentCallVo.getAgentId()) && agentCallVo.getAgentId().equals(sysUser.getAccount())) {
                        agentCallVo.setAgentName(sysUser.getName());
                    }
                }
            }
            log.info("坐席状态统计 - 获取userName - sysUsers:{},agentCallVos:{}", sysUsers, agentCallVos);
        }
        agentStatusVo.setOfficeCallVo(officeCallVo);
        if (!agentCallVos.isEmpty()) {
            agentStatusVo.setAgentCallVos(agentCallVos);
        } else {
            agentStatusVo.setAgentCallVos(new ArrayList<>());
        }

        agentStatusVo.setBiType(StatisticBIConstant.AGENT_STATUS_STATISTICS_DAY);
        agentStatusVo.setBiMonth(ScreenDateUtils.getDate(date.getStartDate()));
        //把vo对象转成jsonstr
        String jsonStr = JSON.toJSONString(agentStatusVo);
        log.info("当天 {} 坐席状态统计 最新一版数据 -> {} ", date, jsonStr);

        biService.insertOnDuplicate(StatisticBIConstant.AGENT_STATUS_STATISTICS_DAY, jsonStr, ScreenDateUtils.getDate(date.getStartDate()));
    }

    //今日通话分析
    @DS("tjzy-async")
    @Override
    public void scheduleBITodayCall(GzxLocalDateTimeVo date) {
        GzxTodayCallVo todayCallVo = new GzxTodayCallVo();
        //平台使用线路数
        int lineNum = biCallRecordMapper.getTodayCallLineNum(date);
        todayCallVo.setLineNum(lineNum);
        //客户地区数量
        int customerAreaNum = biCallRecordMapper.getTodayCallCustomerAreaNum(date);
        todayCallVo.setCustomerAreaNum(customerAreaNum);
        //呼叫总数
        int callNum = biCallRecordMapper.getTodayCallNum(date);
        todayCallVo.setCallNum(callNum);
        //通话总时长
        int totalCallDuration = biCallRecordMapper.getTodayCallTotalCallDuration(date);
        todayCallVo.setTotalCallDuration(totalCallDuration);

        //获取1天的数据 每天所有地区的呼叫量
        List<GzxCommonVo> list = biCallRecordMapper.getCallByArea(date);
        list = list.stream().map(vo -> {
            if (vo.getName() != null) {
                vo.setName(vo.getName().trim());
            }
            return vo;
        }).toList();
        if (!list.isEmpty()) {
            todayCallVo.setCustomerArea(list);
        } else {
            todayCallVo.setCustomerArea(new ArrayList<>());
        }

        todayCallVo.setBiType(StatisticBIConstant.TODAY_CALL_ANALYSIS_DAY);
        todayCallVo.setBiMonth(ScreenDateUtils.getDate(date.getStartDate()));
        //把vo对象转成jsonstr
        String jsonStr = JSON.toJSONString(todayCallVo);
        log.info("当天 {} 今日通话分析 最新一版数据 -> {} ", date, jsonStr);

        biService.insertOnDuplicate(StatisticBIConstant.TODAY_CALL_ANALYSIS_DAY, jsonStr, ScreenDateUtils.getDate(date.getStartDate()));
    }

    //历史接通分析
    @DS("tjzy-async")
    @Override
    public void scheduleBIHistoryAnswer(GzxLocalDateTimeVo date) {
        GzxHistoryAnswerVo historyAnswerVo = new GzxHistoryAnswerVo();

        //历史接通分析 - 活跃线路呼出总数统计
        List<GzxActiveLineVo> activeLineVos = biCallRecordMapper.getHistoryAnswerByTime(date);
        log.info("历史接通分析-过滤掉拨打次数小于一百或者接通率小于1%的数据-过滤前 -> {} ", activeLineVos.size());
        //过滤掉拨打次数小于一百或者接通率小于1%
        activeLineVos = activeLineVos.stream().filter(activeLineVo -> activeLineVo.getCallTotal() >= StatisticBIConstant.CALL_NUM && ((double) activeLineVo.getCallCompletionTotal() / activeLineVo.getCallTotal()) >= StatisticBIConstant.ANSWER_RATE).toList();
        log.info("历史接通分析-过滤掉拨打次数小于一百或者接通率小于1%的数据-过滤后 -> {} ", activeLineVos.size());
        if (!activeLineVos.isEmpty()) {
            //转换线路名称
            List<GzxPredictAllVo> callerInfo = predictAllService.getCallerInfo(ScreenDateUtils.currentMonth());
            //线路callerInfo的caller和activeLineVos的linName相同的，把lineName改成callerInfo的lineName
            for (GzxPredictAllVo predictAll : callerInfo) {
                for (GzxActiveLineVo activeLineVo : activeLineVos) {
                    if (!ObjectUtils.isEmpty(predictAll) && !StringUtils.isEmpty(predictAll.getCaller()) && predictAll.getCaller().equals(activeLineVo.getLineName())) {
                        activeLineVo.setLineName(predictAll.getCallName());
                    }
                }
            }

            historyAnswerVo.setActiveLineCall(activeLineVos);
        } else {
            historyAnswerVo.setActiveLineCall(new ArrayList<>());
        }

        //当天呼叫统计
        GzxCallStatisticVo callStatisticVo = biCallRecordMapper.getCallStatistic(date);
        callStatisticVo.setCurrentDate(ScreenDateUtils.getDate(date.getStartDate()));
        historyAnswerVo.setCallStatisticVo(callStatisticVo);

        //客户分布统计
        List<GzxCustomerDistributionVo> customerDistribution = biCallRecordMapper.getCustomerDistribution(date);
        if (!customerDistribution.isEmpty()) {
            historyAnswerVo.setCustomerDistribution(customerDistribution);
        } else {
            historyAnswerVo.setCustomerDistribution(new ArrayList<>());
        }

        historyAnswerVo.setBiType(StatisticBIConstant.HISTORY_ANSWER_RATE_ANALYSIS_DAY);
        historyAnswerVo.setBiMonth(ScreenDateUtils.getDate(date.getStartDate()));
        //把vo对象转成jsonstr
        String jsonStr = JSON.toJSONString(historyAnswerVo);
        log.info("当天 {} 历史接通分析 最新一版数据 -> {} ", date, jsonStr);

        biService.insertOnDuplicate(StatisticBIConstant.HISTORY_ANSWER_RATE_ANALYSIS_DAY, jsonStr, ScreenDateUtils.getDate(date.getStartDate()));
    }

    //主报表
    @DS("tjzy-async")
    @Override
    public void scheduleBIMain(GzxLocalDateTimeVo date) {
        GzxMainBIVo mainBIVo = new GzxMainBIVo();
        //接通总数，接通总时长（分钟）
        GzxMainBIVo callComplete = biCallRecordMapper.getCallComplete(date);
        mainBIVo.setCallTotal(callComplete.getCallTotal());
        mainBIVo.setTotalCallDuration(callComplete.getTotalCallDuration());

        //呼出总数，活跃坐席数，人均呼叫=呼出总数/活跃坐席数
        GzxMainBIVo callOutgoing = biCallRecordMapper.getCallOutActiveSeat(date);
        mainBIVo.setCallOutgoingTotal(callOutgoing.getCallOutgoingTotal());
        mainBIVo.setActiveAgentTotal(callOutgoing.getActiveAgentTotal());

        //人均载案量
        int averageCallTotal = biCallRecordMapper.getAverageCallTotal(date);
        mainBIVo.setAverageCallTotal(averageCallTotal);

        //团队人均呼叫量排行榜
        List<GzxOfficeCallRankVo> teamAgentVoList = biCallRecordMapper.getTeamAgent(date);
        //deptId下的数据少于50条的都过滤掉
        teamAgentVoList = teamAgentVoList.stream()
                .filter(teamAgentVo -> teamAgentVo.getCallTotalRank() > StatisticBIConstant.FILTER_NUM).toList();
        List<String> orgIds = teamAgentVoList.stream().map(GzxOfficeCallRankVo::getDeptId).toList();
        //为空的不去查询
        if (!orgIds.isEmpty()) {
            //根据deptId获取名称
            List<SysOrg> sysOrgs = getOrgByIds(orgIds);
            //把org中id和office的deptId对应上的赋值给office
            for (GzxOfficeCallRankVo callRankVo : teamAgentVoList) {
                for (SysOrg sysOrg : sysOrgs) {
                    //非空校验
                    if (!StringUtils.isEmpty(callRankVo.getDeptId()) && callRankVo.getDeptId().equals(sysOrg.getId())) {
                        callRankVo.setDeptName(sysOrg.getName());
                    }
                }
            }
            log.info("主报表 - 获取deptName - sysOrgs:{},teamAgentVoList:{}", sysOrgs, teamAgentVoList);
        }
        if (!teamAgentVoList.isEmpty()) {
            mainBIVo.setTeamAgentVoList(teamAgentVoList);
        } else {
            mainBIVo.setTeamAgentVoList(new ArrayList<>());
        }

        //坐席呼叫量排行榜
        List<GzxAgentCallRankVo> agentCallRankVoList = biCallRecordMapper.getAgentCallRank(date);
        List<String> userIds = agentCallRankVoList.stream().map(GzxAgentCallRankVo::getAgentId).toList();
        if (!userIds.isEmpty()) {
            List<SysUser> sysUsers = getUserByIds(userIds);
            //把user中id和agentCallVos的id对应上的赋值给agentCallVos
            for (GzxAgentCallRankVo callRankVo : agentCallRankVoList) {
                for (SysUser sysUser : sysUsers) {
                    //非空校验
                    if (!StringUtils.isEmpty(callRankVo.getAgentId()) && callRankVo.getAgentId().equals(sysUser.getAccount())) {
                        callRankVo.setAgentName(sysUser.getName());
                    }
                }
            }
            log.info("主报表 - 获取userName - sysUsers:{},agentCallRankVoList:{}", sysUsers, agentCallRankVoList);
        }
        //根据deptIds获取名称
        List<String> orgIds2 = agentCallRankVoList.stream().map(GzxAgentCallRankVo::getDeptId).toList();
        //为空的不去查询
        if (!orgIds2.isEmpty()) {
            //根据deptId获取名称
            List<SysOrg> sysOrgs = getOrgByIds(orgIds2);
            //把org中id和office的deptId对应上的赋值给office
            for (GzxAgentCallRankVo callRankVo : agentCallRankVoList) {
                for (SysOrg sysOrg : sysOrgs) {
                    //非空校验
                    if (!StringUtils.isEmpty(callRankVo.getDeptId()) && callRankVo.getDeptId().equals(sysOrg.getId())) {
                        callRankVo.setDeptName(sysOrg.getName());
                    }
                }
            }
            log.info("坐席状态统计 - 获取deptName - sysOrgs:{},agentCallRankVoList:{}", sysOrgs, agentCallRankVoList);
        }
        if (!agentCallRankVoList.isEmpty()) {
            mainBIVo.setAgentCallRankVoList(agentCallRankVoList);
        } else {
            mainBIVo.setAgentCallRankVoList(new ArrayList<>());
        }

        //客户分布地区
        List<GzxAreaVo> areaVoList = biCallRecordMapper.getAreaByDay(date);
        //根据area去空格
        areaVoList = areaVoList.stream().map(vo -> {
            if (vo.getAreaName() != null) {
                vo.setAreaName(vo.getAreaName().trim());
            }
            return vo;
        }).toList();
        if (!areaVoList.isEmpty()) {
            mainBIVo.setAreaVoList(areaVoList);
        } else {
            mainBIVo.setAreaVoList(new ArrayList<>());
        }

        mainBIVo.setBiType(StatisticBIConstant.MAIN_STATISTICS_DAY);
        mainBIVo.setBiMonth(ScreenDateUtils.getDate(date.getStartDate()));
        //把vo对象转成jsonstr
        String jsonStr = JSON.toJSONString(mainBIVo);
        log.info("当天 {} 主报表 最新一版数据 -> {} ", date, jsonStr);

        biService.insertOnDuplicate(StatisticBIConstant.MAIN_STATISTICS_DAY, jsonStr, ScreenDateUtils.getDate(date.getStartDate()));
    }

    //跑当月所有数据
    @DS("tjzy-async")
    @Override
    public Void runBI() {
        List<GzxLocalDateTimeVo> list = ScreenDateUtils.getMonthListDate();
        log.info("跑当月所有数据--------------->报表统计任务{} ", CommonDateUtil.getCurrentTimeStr());
        for (GzxLocalDateTimeVo date : list) {
            long beginTime = System.currentTimeMillis();
            //本月通话统计
            scheduleBIMonthCall(date);
            log.info("本月通话统计 {} 号 执行时间: {} 毫秒", date, System.currentTimeMillis() - beginTime);
            //团队坐席统计
            long teamAgentTime = System.currentTimeMillis();
            scheduleBITeamAgent(date);
            log.info("团队坐席统计 {} 号 执行时间: {} 毫秒", date, System.currentTimeMillis() - teamAgentTime);
            //通话趋势分析
            long callTrendTime = System.currentTimeMillis();
            scheduleBICallTrend(date);
            log.info("通话趋势分析 {} 号 执行时间: {} 毫秒", date, System.currentTimeMillis() - callTrendTime);
            //坐席状态统计
            long agentStatusTime = System.currentTimeMillis();
            scheduleBIAgentStatus(date);
            log.info("坐席状态统计 {} 号 执行时间: {} 毫秒", date, System.currentTimeMillis() - agentStatusTime);
            //今日通话分析
            long todayCallTime = System.currentTimeMillis();
            scheduleBITodayCall(date);
            log.info("今日通话分析 {} 号 执行时间: {} 毫秒", date, System.currentTimeMillis() - todayCallTime);
            //历史接通分析
            long historyAnswerTime = System.currentTimeMillis();
            scheduleBIHistoryAnswer(date);
            log.info("历史接通分析 {} 号 执行时间: {} 毫秒", date, System.currentTimeMillis() - historyAnswerTime);
            //主报表
            long mainTime = System.currentTimeMillis();
            scheduleBIMain(date);
            log.info("主报表 {} 号 执行时间: {} 毫秒", date, System.currentTimeMillis() - mainTime);

            log.info("报表统计任务 {} 号 执行时间: {} 毫秒", date, System.currentTimeMillis() - beginTime);
        }
        return null;
    }

    @DS("tjzy-async")
    @Override
    public Void runDateBI(String currentDate) {
        GzxLocalDateTimeVo date = ScreenDateUtils.getNowDate();
        log.info("跑某天所有数据--------------->报表统计任务{} ", CommonDateUtil.getCurrentTimeStr());
        long beginTime = System.currentTimeMillis();
        //本月通话统计
        scheduleBIMonthCall(date);
        log.info("本月通话统计 {} 号 执行时间: {} 毫秒", date, System.currentTimeMillis() - beginTime);
        //团队坐席统计
        long teamAgentTime = System.currentTimeMillis();
        scheduleBITeamAgent(date);
        log.info("团队坐席统计 {} 号 执行时间: {} 毫秒", date, System.currentTimeMillis() - teamAgentTime);
        //通话趋势分析
        long callTrendTime = System.currentTimeMillis();
        scheduleBICallTrend(date);
        log.info("通话趋势分析 {} 号 执行时间: {} 毫秒", date, System.currentTimeMillis() - callTrendTime);
        //坐席状态统计
        long agentStatusTime = System.currentTimeMillis();
        scheduleBIAgentStatus(date);
        log.info("坐席状态统计 {} 号 执行时间: {} 毫秒", date, System.currentTimeMillis() - agentStatusTime);
        //今日通话分析
        long todayCallTime = System.currentTimeMillis();
        scheduleBITodayCall(date);
        log.info("今日通话分析 {} 号 执行时间: {} 毫秒", date, System.currentTimeMillis() - todayCallTime);
        //历史接通分析
        long historyAnswerTime = System.currentTimeMillis();
        scheduleBIHistoryAnswer(date);
        log.info("历史接通分析 {} 号 执行时间: {} 毫秒", date, System.currentTimeMillis() - historyAnswerTime);
        //主报表
        long mainTime = System.currentTimeMillis();
        scheduleBIMain(date);
        log.info("主报表 {} 号 执行时间: {} 毫秒", date, System.currentTimeMillis() - mainTime);

        log.info("报表统计任务 {} 号 执行时间: {} 毫秒", date, System.currentTimeMillis() - beginTime);
        return null;
    }

    //跑当月数据，只跑一次
    @DS("tjzy-async")
    @Override
    public void scheduleBIMonth(GzxLocalDateTimeVo date) {
        try {
            runBI();
        } catch (Exception e) {
            log.error("跑当月数据异常 {} ", e);
        }
    }

    // 填充空余时间段的数据
    private List<Map<String, String>> fillMissingDates(List<Map<String, String>> list, String month) {
        List<Map<String, String>> dateList = new ArrayList<>();
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.YEAR, Integer.parseInt(month.split("-")[0]));
        calendar.set(Calendar.MONTH, Integer.parseInt(month.split("-")[1]) - 1);
        calendar.set(Calendar.DAY_OF_MONTH, 1);
        int daysInMonth = calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
        // 获取当前日期
        Date currentDate = new Date();
        for (int day = 1; day <= daysInMonth; day++) {
            //只获取从月初到当天日期
            if (calendar.getTime().before(currentDate) || calendar.getTime().equals(currentDate)) {
                calendar.set(Calendar.DAY_OF_MONTH, day);
                String date = ScreenDateUtils.getMonthDay();
                Map<String, String> newDateMap = new HashMap<>(); // 创建一个新的 Map 对象
                newDateMap.put(StatisticBIConstant.DATE_KEY, date);
                newDateMap.put(StatisticBIConstant.SEATS_KEY, "0");
                for (Map<String, String> entry : list) {
                    String entryDate = ObjectUtils.isNull(entry.get(StatisticBIConstant.DATE_KEY)) ? "" : entry.get(StatisticBIConstant.DATE_KEY).trim();
                    if (date.equals(entryDate)) {
                        newDateMap.put(StatisticBIConstant.SEATS_KEY, String.valueOf(entry.getOrDefault(StatisticBIConstant.SEATS_KEY, "0")));
                    }
                }
                dateList.add(newDateMap); // 添加新的 Map 对象到 dateList
                log.info("calendar -> {} ", calendar.getTime());
                calendar.add(Calendar.DAY_OF_MONTH, 1);
            }
        }
        return dateList;
    }
}
